Aspect oriented programming (AOP) is a software development paradigm for providing application code which more accurately reflects an application design. In this way, AOP provides for simplified application development and maintenance. AOP achieves this by recognising how aspects of an application, known as “concerns”, can cut across the entire application. For example, concerns such as security, tracing and logging can be fundamental to application design and can affect most or all of an application. AOP allows for such concerns to be extracted and designed independently of other concerns, whilst being implemented in a way which potentially affects an entire application as appropriate. Concrete means of achieving these objectives include join points, pointcut expressions and advice. These means and associated techniques are considered in detail in existing AOP literature such as the “AspectJ Programming Guide* (available at eclipse.org/aspectj/doc/progguide/index.html) and are further considered below (AspectJ is a registered trademark of Palo Alto Research Center Incorporated).
One technology for employing AOP in software development is known as Aspectj. AspectJ provides for the compilation of aspect oriented applications in the Java language (Java is a registered trademark of Sun Microsystems). The conventions and program fragments used herein generally relate to AspectJ, although it will be apparent to those skilled in the art that the concepts and techniques are equally applicable to the generic field of AOP and any particular aspect oriented software development implementation.
A joint point in a software application is a well defined point in a program flow. For example, the actions of an object receiving a method call is a clearly definable point in a program flow, and is known as a method call join point. Other examples of join points include the execution of a method body, references to fields or the execution of an exception handler. Join points can be identified and used in an aspect oriented application through a definition of an expression known as a pointcut. For example, a pointcut defined as:
pointcut radiusUpdate( ):call(void Circle.setRadius(long)) relates to each join point that is a call to a method having the signature “Circle.setRadius(long)”. Once defined, pointcuts are used to provide code, known as advice, which can be executed at runtime when a join point is reached.
Pointcuts are typically defined in terms of the syntactic structure of program code, such as with reference to particular method and field names or though the use of wildcards. This is explained by way of example using the simple Java class “Circle” defined below. Each instance of the “Circle” class has an associated radius, colour and center point, each of which can be set on instantiation and via setter methods (“setRadius’, “setColour* and “setCenter” respectively). The “Circle” class further provides getter methods to return the value of each of these attributes, and an additional method for providing the area of the circle. Finally, the class includes a “move” method for moving the centerpoint of the circle by a defined offset in x and y dimensions.
public class Circle{long radius;Colour colour;Point center;public Circle(long radius, Point center, Colour colour)  { this.radius = radius; this.center = center;   this.colour = colour; }public void setRadius(long radius) { this.radius = radius; }public void setColour (Colour colour) { this.colour = colour; }public void setCenter(Point center) { this.center = center; }public long getRadius ( ) { return this.radius; }public Colour getColour( ) { return this.colour; }public Point getCenter( ) { return this.center; }public long getArea ( ) { return (pi * sqr(this.radius)); }public void move(int x, int y) { center = center.moveBy(x,y); }}
Consider now a design requirement in a software application to respond to an update to any of the attributes of instances of the “Circle” class. Using existing AOP techniques, a pointcut expression can be defined in view of the definition of the “Circle” class as follows:
pointcut circleUpdate( ):execution(* Circle.set*( . . . ))
Such a pointcut expression includes each join point that is the execution of a method of the “Circle” class having the signature “*set*( . . . )”. I.e. any method having a name starting with “set”. While this includes the setter methods of the “Circle” class, it notably excludes the move method. Thus, with insight of the design and structure of the Circle class it is necessary to expand on the defined pointcut expression as follows:
pointcut circleUpdate( ) :execution(* Circle.set*(..)) ∥execution (void Circle.move(int, int))
Thus, the pointcut expression is extended to include the join point that is a call to the “Circle.move” method. In this way it is possible to provide advice associated with such a pointcut expression for the update of “Circle” instances.
Whilst this approach is effective for those join points explicitly captured by the pointcut expression, there is still a gap between the design requirement and the code. Recall that the design requirement is to respond to an update to any of the attributes of instances of the “Circle” class. The pointcut expression defined above is effective only insofar as it is dependent upon the syntactical structure of the “Circle” class. For example, the pointcut expression is tightly coupled to the particular naming convention used in the class definition since it relies on the use of the “set . . . ” convention for setter methods. This has the disadvantage that methods which are not setter methods but which also have a name prefix of “set” (such as a method named “settlement”) would incorrectly satisfy the criteria of the pointcut expression. Further, the pointcut expression relies on the programmers knowledge of the class to determine that the join point that is a call to the “Circle.move” method should also be included in the definition of the pointcut expression. Consequently, any changes to the “Circle” class which affects these tight couplings to the pointcut definition would render the pointcut ineffective. Similarly, updates to a circle instance which take place outside the join points within the definition of the pointcut expression (such as in a separate class altogether) would not be captured by the pointcut expression. Thus the definition of pointcut expressions in this way provides a merely syntactic, and not semantic, relationship with the application code.
One improvement in the field of AOD for enhancing the relationship between the definition of pointcut expressions and application code is to employ metadata within application code as a basis for the definition of pointcut expressions. Such metadata can be used to draw together parts of an application which deal with a common concern across the entire application. An example of metadata which can be used in this way is the annotation facility provided in the Java programming language, with which any Java member declaration or definition can be supplemented by metadata. For example, the “Circle” class provided above can be amended by the inclusion of annotation metadata at each and every point that an update to a circle is made. The “Circle” class below has been supplemented with a Java annotation *@A” at each point an update to a circle is made.
public class Circle{long radius;Colour colour;Point center;public Circle(long radius, Point center, Colour colour)  { this.radius = radius; this.center = center;   this.colour = colour; }@A public void setRadius(long radius) { this.radius = radius; }@A public void setColour(Colour colour) { this.colour = colour; }@A public void setCenter(Point center) { this.center = center; }public long getRadius( ) { return this.radius; }public Colour getColour( ) { return this.colour; }public Point getCenter( ) { return this.center; }public long getArea( ) { return (pi * sqr(this.radius)); }@A public void move(int x, int y) { center = center.moveBy(x,y); }}
A pointcut expression can then be defined using the annotation metadata as follows:
pointcut circleUpdate( ):execution(@A * *( . . . ))
In this way the pointcut can be written at a higher level of abstraction. However, it remains necessary for a programmer to apply the annotations to application source code in order that each and every join point is captured by the pointcut definition. Thus, even with the use of annotations, the pointcut expression is coupled to application code syntactically.
In order to define pointcuts which correspond to the semantic meaning of the application (e.g. capturing all join points throughout an application which result in an update to a circle in accordance with the design requirement) it is necessary for programmers to provide application metadata in view of the entire application in accordance with the design. However, application development is typically organised into components such that programmers work with individual components and the entire application is not brought together until build time, or even later (runtime). This is especially the case for library based software development which can be distributed across development teams, organisations and geographies. It is therefore not always possible for an application developer to introduce metadata corresponding to a concern which cuts across the entire application. Thus, in a sense, software developers are presented with the same problem of efficiently managing cross-cutting concerns which AOD was developed to address.
It would therefore be advantageous to provide for the definition of pointcuts based on their semantic intent, such that the development of an application can correspond closely to the requirements of the application design.